package org.lex.utils;

/**
 * A CategoryComparator is used to reorder the elements .
 * <p>
 * The default <code>compare</code> method compares elements using two steps.
 * The first step uses the values returned from <code>getCategory()</code>. By
 * default, all elements are in the same category. The second level is based on
 * the Comparable in same category.
 * </p>
 * <p>
 * Subclasses may reimplement the <code>getCategory()</code> method to provide
 * categorization; and they may override the <code>compare</code> methods to
 * provide a totally different way of sorting elements.
 * </p>
 */
public interface CategoryComparator<T> {
	/**
	 * Returns the category of the given element. The category is a number used
	 * to allocate elements to bins; the bins are arranged in ascending numeric
	 * order. The elements within a bin are arranged via a second level sort
	 * criterion.
	 * <p>
	 * The default implementation of this framework method returns
	 * <code>0</code>. Subclasses may reimplement this method to provide
	 * non-trivial categorization.
	 * </p>
	 * 
	 * @param element
	 *            the element
	 * @return the category
	 */
	public int getCategory(T element);

	/**
	 * Returns a negative, zero, or positive number depending on whether the
	 * first element is less than, equal to, or greater than the second element.
	 * <p>
	 * The default implementation of this method is based on comparing the
	 * elements' categories as computed by the <code>getCategory()</code>
	 * framework method. Elements within the same category are further subjected
	 * to Comparable<T>.
	 * </p>
	 * 
	 * @param e1
	 *            the first element
	 * @param e2
	 *            the second element
	 * @return a negative number if the first element is less than the second
	 *         element; the value <code>0</code> if the first element is equal
	 *         to the second element; and a positive number if the first element
	 *         is greater than the second element
	 */
	public int compare(T e1, T e2);
}
